/*
 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef M2M_CLOUD_CONTEXT_H
#define M2M_CLOUD_CONTEXT_H
#include <stdint.h>
#include "comm_def.h"
#include "utils_fsm.h"
#include "service_manager.h"
#include "coap_endpoint.h"
#include "coap_endpoint_event_source.h"
#include "coap_endpoint_client.h"
#include "iotc_svc_dev.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SESS_HMAC_LEN   32
#define M2M_CLOUD_URL_NUM 3
#define RAND_SN_LEN     8
#define SALT_LEN        (RAND_SN_LEN * 2)
#define SESSION_KEY_LEN 32
#define ITER_TIMES          1 /* 基于authcode派生，迭代一次表示依赖authcode安全强度 */
#define REQ_ID_LEN          20
#define SESSION_AUTHCODE_LEN 16

typedef enum {
    M2M_CLOUD_FSM_STATE_INIT = 0,
    M2M_CLOUD_FSM_STATE_CREATE_LINK,
    M2M_CLOUD_FSM_STATE_CONNECT,
    M2M_CLOUD_FSM_STATE_PSK,
    M2M_CLOUD_FSM_STATE_PSK_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_REGISTER,
    M2M_CLOUD_FSM_STATE_REGISTER_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_LOGIN,
    M2M_CLOUD_FSM_STATE_LOGIN_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_AUTHCODE,
    M2M_CLOUD_FSM_STATE_AUTHCODE_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_REVOKE,
    M2M_CLOUD_FSM_STATE_REVOKE_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_DEV_INFO_SYNC,
    M2M_CLOUD_FSM_STATE_DEV_INFO_SYNC_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_ONLINE,
    M2M_CLOUD_FSM_STATE_DELETE,
    M2M_CLOUD_FSM_STATE_GET_AUTHCODE,
    M2M_CLOUD_FSM_STATE_GET_AUTHCODE_WAIT_RESP,
    M2M_CLOUD_FSM_STATE_EXIT,
} M2mCloudFsmState;

typedef enum {
    M2M_CLOUD_CTX_BIT_REGISTER = 0,
    M2M_CLOUD_CTX_BIT_REVOKE,
    M2M_CLOUD_CTX_BIT_ENABLE_BACKOFF,
    M2M_CLOUD_CTX_BIT_LOGIN_INFO_READY,
} M2mCloudContextBitMap;

typedef struct M2mCloudContext M2mCloudContext;

struct M2mCloudContext {
    uint32_t bitMap;
    struct {
        int32_t regTimer;
        int32_t fsmTimer;
        int32_t tokenTimer;
        int32_t hbTimer;
        UtilsFsm *fsmCtx;
    } stateManager;
    struct {
        int32_t instanceId;
        ServiceFinishCallback onFinish;
    } svcInfo;
    union {
        DevLoginInfo loginInfo;
        DevRegInfo regInfo;
    } authInfo;
    struct {
        uint16_t port;
        uint16_t urlIndex;
        const char *url[M2M_CLOUD_URL_NUM];
        void (*cloudLinkErrorCallback)(M2mCloudContext *ctx);
        TransSocket *socket;
        TransLink *link;
        TransSess *sess;
        void *sessData;
        UtilsBufferCtx *sendBuf;
        UtilsBufferCtx *recvBuf;
        CoapEndpoint *endpoint;
        EventSource *coapSource;
    } linkInfo;
    struct {
        char access[CLOUD_ACCESS_TOKEN_STR_LEN + 1];
        char refresh[CLOUD_REFRESH_TOKEN_STR_LEN + 1];
        uint32_t timeout;
        uint32_t updateTime;
        uint32_t cnt;
    } tokenInfo;
    struct {
        uint8_t cnt;
        uint32_t before;
        uint32_t interval;
    } backoffInfo;
    struct {
        bool pskFinish;
        bool encrypt;
        uint8_t salt[SALT_LEN];
        uint8_t key[SESSION_KEY_LEN];
    }pskInfo;
    struct {
        bool acFinish;
        int32_t timeout;
        uint8_t authCode[SESSION_AUTHCODE_LEN];
        uint8_t authCodeId[SESSION_AUTHCODE_LEN];
    }authCodeInfo;
    struct {
        uint16_t sentCnt;
        uint32_t interval;
    } heartbeatInfo;
    char reqId[HEXIFY_LEN(REQ_ID_LEN) + 1];
};

M2mCloudContext *GetM2mCloudCtx(void);

int32_t M2mCloudCtxInit(void);

#ifdef __cplusplus
}
#endif

#endif /* M2M_CLOUD_CONTEXT_H */